package app.server.project.main.service.db.entity.user;

import app.server.project.core.constants.Def;
import app.server.project.core.syndb.SynDBMgr;
import app.server.project.core.util.MathUtil;
import app.server.project.main.service.db.entity.cfg.RaceCfgEntity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Transient;
import lombok.Data;
import org.hibernate.annotations.Comment;

import java.time.LocalDateTime;
import java.util.Objects;

@Data
@Entity(name = "user_race")
@TableName("user_race")
@Comment(value = "用户赛道资源表")
public class UserRaceEntity {

    @Id
    @Column(name = "id")
    @Comment("用户主键")
    @TableId("id")
    @JsonIgnore
    private long Id;


    @TableField("user_id")
    @Column(name = "user_id")
    @Comment("用户主键")
    @JsonIgnore
    private long userId;

    /**
     * 赛道id
     */
    @TableField("race_id")
    @Comment("赛道id")
    @Column(name = "race_id")
    private int raceId;

    /**
     * 数值
     */
    @TableField("val")
    @Comment("数值")
    @Column(name = "val")
    private long val;

    @TableField("update_time")
    @Comment("更新时间")
    @Column(name = "update_time")
    @JsonIgnore
    private LocalDateTime updateTime;


    /**
     * 点击次数
     */
    @TableField("click_num")
    @Comment("点击次数")
    @Column(name = "click_num")
    private long clickNum;

    /**
     * 数值
     */
    @TableField("ton_lock")
    @Comment("ton充值")
    @Column(name = "ton_lock")
    private int tonLock;


    /**
     * 提现金额
     */
    @Column(name = "activity_free_num")
    @Comment("活动次数免费次数")
    @TableField("activity_free_num")
    private long activityFreeNum;
    /**
     * 提现金额
     */
    @Column(name = "activity_free_time")
    @Comment("活动免费时间")
    @TableField("activity_free_time")
    private LocalDateTime activityFreeTime;

    @JsonIgnore
    @Transient
    @TableField(exist = false)
    private boolean synDb = false;

    @TableField(exist = false)
    @Transient
    private long weekFreeNum;

    public static UserRaceEntity of(long userId, int raceId, long id) {
        UserRaceEntity userInfoEntity = new UserRaceEntity();
        userInfoEntity.setId(id);
        userInfoEntity.setSynDb(true);
        userInfoEntity.setUserId(userId);
        userInfoEntity.setRaceId(raceId);
        userInfoEntity.setUpdateTime(LocalDateTime.now());
        return userInfoEntity;
    }


    public void addClickNum() {
        var ret = MathUtil.canAddNum(this.clickNum, 1);
        this.clickNum += ret;
        this.setClickNum(this.clickNum);
    }

    public void setClickNum(long clickNum) {
        this.clickNum = clickNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getClickNum, this);
    }


    public void setUserId(long userId) {
        this.userId = userId;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getUserId, this);
    }

    public void setRaceId(int raceId) {
        this.raceId = raceId;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getRaceId, this);
    }


    public void setTonLock(int tonLock) {
        this.tonLock = tonLock;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getTonLock, this);
    }


    public void setVal(long val) {
        this.val = val;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getVal, this);
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getUpdateTime, this);
    }

    public void addVal(long num) {
        var ret = MathUtil.canAddNum(this.val, num);
        this.val += ret;
        this.setVal(this.val);
    }

    public void consumeVal(long num) {
        if (Def.Zero >= num) return;
        if (num >= this.val) {
            this.setVal(Def.Zero);
        } else {
            this.val -= num;
            this.setVal(this.val);
        }
    }

    public void setActivityFreeNum(long activityFreeNum) {
        this.activityFreeNum = activityFreeNum;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getActivityFreeNum, this);
    }

    public void setActivityFreeTime(LocalDateTime activityFreeTime) {
        this.activityFreeTime = activityFreeTime;
        if (!this.synDb) return;
        SynDBMgr.addChangeData(UserRaceEntity::getActivityFreeTime, this);
    }

    public void addActivityFreeNum() {
        this.activityFreeNum += 1;
        this.setActivityFreeNum(this.activityFreeNum);
    }

    public void resetFreeNum(RaceCfgEntity cfg) {
        if (cfg.getFreeStatus() == Def.FALSE) return;
        var localNow = LocalDateTime.now();
        if (Objects.nonNull(cfg.getStartTime()) && Objects.nonNull(cfg.getEndTime())) {
            if (!(cfg.getStartTime().isBefore(localNow) && cfg.getEndTime().isAfter(localNow))) {
                return;
            }
        }

        //免费次数开关
        if (cfg.getFreeStatus() == Def.True) {
            if (Objects.isNull(this.activityFreeTime)) {
                this.setActivityFreeTime(localNow);
            }
            if (Objects.nonNull(cfg.getStartTime()) && Objects.nonNull(cfg.getEndTime())) {
                if (cfg.getStartTime().isAfter(this.activityFreeTime)) {
                    //开始重置
                    this.setActivityFreeTime(localNow);
                    this.setActivityFreeNum(Def.Zero);
                }
            }
        }
    }

    public boolean canClick(RaceCfgEntity cfg) {
        return this.getActivityFreeNumByCfg(cfg) > Def.Zero;
    }

    public int getActivityFreeNumByCfg(RaceCfgEntity cfg) {
        this.resetFreeNum(cfg);
        if (cfg.getFreeStatus() == Def.FALSE) return Def.Zero;
        var localNow = LocalDateTime.now();
        if (Objects.nonNull(cfg.getStartTime()) && Objects.nonNull(cfg.getEndTime())) {
            if (!(cfg.getStartTime().isBefore(localNow) && cfg.getEndTime().isAfter(localNow))) {
                return Def.Zero;
            }
        }
        //免费次数开关
        if (cfg.getFreeStatus() == Def.True) {
            if (Objects.nonNull(cfg.getStartTime()) && Objects.nonNull(cfg.getEndTime())) {
                if (cfg.getStartTime().isBefore(this.activityFreeTime)
                        && cfg.getEndTime().isAfter(this.activityFreeTime)) {
                    //开始重置
                    return Math.toIntExact(cfg.getFreeNum() - this.activityFreeNum);
                }
            }
        }
        return Def.Zero;
    }

}
